import 'unit.dart';
import 'widgets/node.dart';

class _Viewport {
  /// 视口宽度
  int width = 375;

  /// 视口高度
  int height = 600;

  /// 默认字体大小
  double rem = 14;

  /// 设备像素比
  double devicePixelRatio = 1;
}

// 视口
final viewport = _Viewport();

/// CSS尺寸
class CSSSize {
  static final _converts = [
    CSSUnit.px,
    CSSUnit.ppx,
    CSSUnit.rpx,
    CSSUnit.percent,
    CSSUnit.rem,
    CSSUnit.em,
    CSSUnit.vw,
    CSSUnit.vh,
    CSSUnit.vmin,
    CSSUnit.vmax,
  ];

  double value = 0;

  CSSUnit unit = CSSUnit.px;

  CSSSize(this.value, this.unit);

  CSSSize.px(this.value);

  CSSSize.ppx(this.value) {
    this.unit = CSSUnit.ppx;
  }

  CSSSize.rpx(this.value) {
    this.unit = CSSUnit.rpx;
  }

  CSSSize.percent(this.value) {
    this.unit = CSSUnit.percent;
  }

  CSSSize.rem(this.value) {
    this.unit = CSSUnit.rem;
  }

  CSSSize.em(this.value) {
    this.unit = CSSUnit.em;
  }

  CSSSize.vw(this.value) {
    this.unit = CSSUnit.vw;
  }

  CSSSize.vh(this.value) {
    this.unit = CSSUnit.vh;
  }

  CSSSize.vmin(this.value) {
    this.unit = CSSUnit.vmin;
  }

  CSSSize.vmax(this.value) {
    this.unit = CSSUnit.vmax;
  }

  CSSSize.from(dynamic json) {
    this.value = json[0];

    if (json.length < 2) {
      this.unit = _converts[json[1]];
    }
  }

  double _getFontSize(CSSNodeData? data, double value) {
    while (data != null) {
      if (data.fontSize > 0) {
        return data.fontSize * value;
      }

      data = data.parent;
    }

    return 0;
  }

  double compute(CSSNodeData data, double percentSize) {
    switch (unit) {
      case CSSUnit.px:
      case CSSUnit.ppx:
        return value;

      case CSSUnit.rpx:
        return value * viewport.width / 750;

      case CSSUnit.percent:
        return value * percentSize;

      case CSSUnit.rem:
        return value * viewport.rem;

      case CSSUnit.em:
        return _getFontSize(data, value);

      case CSSUnit.vw:
        return value * viewport.width / 100;

      case CSSUnit.vh:
        return value * viewport.height / 100;

      case CSSUnit.vmin:
        return value *
            (viewport.width <= viewport.height
                ? viewport.width
                : viewport.height) /
            100;

      case CSSUnit.vmax:
        return value *
            (viewport.width >= viewport.height
                ? viewport.width
                : viewport.height) /
            100;
    }
  }
}
